import { deepMerge } from '@/utils'

export const qs = {
  stringify(obj, options: {
    arrayFormat?: 'repeat' | 'indices' | 'brackets'
  } = {}) {
    const { arrayFormat = 'repeat' } = options

    function buildQueryString(prefix, value) {
      if (value === null || value === undefined) {
        return ''
      }

      if (Array.isArray(value)) {
        return value.reduce((acc, item, index) => {
          const key = arrayFormat === 'indices'
            ? `${prefix}[${index}]`
            : arrayFormat === 'brackets'
              ? `${prefix}[]`
              : prefix
          return acc.concat(buildQueryString(key, item))
        }, []).filter(Boolean).join('&')
      }

      if (typeof value === 'object') {
        return Object.keys(value).reduce((acc, key) => {
          return acc.concat(buildQueryString(`${prefix}[${encodeURIComponent(key)}]`, value[key]))
        }, []).filter(Boolean).join('&')
      }

      return `${encodeURIComponent(prefix)}=${encodeURIComponent(value)}`
    }

    return Object.keys(obj)
      .map(key => buildQueryString(key, obj[key]))
      .filter(Boolean)
      .join('&')
  },
  parse(query) {
    if (!query) {
      return {}
    }
    // 处理完整URL的情况
    const queryString = query.includes('?') ? query.split('?')[1] : query

    return queryString.split('&').reduce((acc, cur) => {
      if (!cur)
        return acc

      const [key, value] = cur.split('=').map(decodeURIComponent)

      // 处理数组格式 a[0]=1&a[1]=2 或 a[]=1&a[]=2
      const matches = key.match(/^([^[]+)\[(\d*)\]$/)
      if (matches) {
        const arrayKey = matches[1]
        const arrayIndex = matches[2]

        if (!acc[arrayKey])
          acc[arrayKey] = []

        if (arrayIndex) {
          // indices 格式
          acc[arrayKey][Number.parseInt(arrayIndex)] = value
        } else {
          // brackets 格式
          acc[arrayKey].push(value)
        }
        return acc
      }

      // 处理对象格式 a[b]=1
      const objMatches = key.match(/^([^[]+)\[([^\]]+)\]$/)
      if (objMatches) {
        const objKey = objMatches[1]
        const propKey = objMatches[2]

        if (!acc[objKey])
          acc[objKey] = {}
        acc[objKey][propKey] = value
        return acc
      }

      // 普通键值对
      acc[key] = value
      return acc
    }, {})
  },
  setQueryString(url: string, query: Record<string, any>) {
    if (!url) {
      return ''
    }
    const queryObj = this.parse(url || '')
    const resObj = deepMerge(queryObj, query)
    const pureUrl = url.includes('?') ? url.split('?')[0] : url
    return `${pureUrl}?${this.stringify(resObj)}`
  },
  getQueryString(url: string, key: string) {
    if (!url) {
      return ''
    }
    return this.parse(url)[key] || ''
  },
}
